import { Container } from 'pixi.js'
import { clipAfterimageHit } from "../clipAfterimage.js";
import { clipMob } from "../mobClip.js";
import share from "../share.js";
import { applyMixins } from "../util.js";
import sceneContainer from "../scene/container.js";
export class Mob {
  constructor(resource, info) {
    this.info = info;
    this.mobId = info.id + '.img';
    this.mobInfo = {};
    // Hurt
    this.fh = Number(info.fh);
    this.numberArray = [];
    this.numSpeed = 1;
    this.numHeight = 40;

    this.ability = {
      maxHP: undefined,
      bodyAttack: undefined,
      nowHP: undefined
    };

    window.mob = this;
    this.state = "";
    
    this.leftEdge = 0;
    this.rightEdge = 0;
    this.resource = resource;
    this.container = new Container();
    this.container.sortableChildren = true;
    let _position = {
      x: 500,
      y: 395,
    };
    this.position = new Proxy(_position, {
      set: (target, key, value) => {
        if (key === "x") {
          this.container[key] = Number(value);
        }
        if (key === "y") {
          this.container[key] = Number(value);
        }
        return Reflect.set(target, key, value);
      },
    });
    this.performance = {
      move: null,
      stand: null,
      hit1: null,
      die1: null,
    };
    this.afterImageHit = {
      sword1: null,
    };
    this.xSpeed = 0.65;

    // 为true，表示死亡
    this.isDie = false;
    //为true，表示正在被攻击。
    this.isAttacked = false;
  }

  async load() {
    await this.resource.load("Mob", `./Mob/${this.mobId}.json`);
  }

  async init() {
    await this.load()
    this.mobInfo = this.resource.Content.Mob[this.mobId].info;
    this.ability = {
      maxHP: Number(this.mobInfo.maxHP),
      bodyAttack: Number(this.mobInfo.bodyAttack),
      nowHP: Number(this.mobInfo.maxHP)
    };
    for (let key in this.performance) {
      this.performance[key] = await clipMob(this.resource, this.mobId, key);
      this.performance[key].updateAnchor = true;
      this.performance[key].animationSpeed = 0.05;
      switch (key) {
        case 'die1':
          this.performance[key].animationSpeed = 0.1;
          break;
        case 'hit1':
          this.performance[key].animationSpeed = 0.08;
          break;
      }
    }
    for (let key in this.afterImageHit) {
      this.afterImageHit[key] = await clipAfterimageHit(this.resource, key);
      this.afterImageHit[key].animationSpeed = 0.1;
      this.afterImageHit[key].loop = false;
    }

    this.transform("move");
    const x = Number(this.info.x);
    // const x = Number(this.info.rx0) + (Number(this.info.rx1) - Number(this.info.rx0)) * Math.random();
    const y = Number(this.info.cy);
    this.position.x = x;
    this.position.y = y;
    this.footholdtree = sceneContainer.footholdtree.footholdTree;
    this.foothold = this.footholdtree[this.fh];

    this.performance.hit1.loop = false;
    this.performance.stand.loop = false;
    this.performance.die1.loop = false;

    this.performance.hit1.onComplete = () => {
      if (this.isDie) {
        this.transform('die1');
      } else {
        this.transform('move');
      }
      this.isAttacked = false;

    }
    this.performance.die1.onComplete = () => {
      this.container.visible = false;
    }
  }

  update() {
    if (this.isLeft() && !this.isDie && !this.isAttacked) {
      this.position.x -= this.xSpeed;
      if (this.position.x < this.foothold.x1) {
        if (this.foothold.isWall()) {
          this.position.x += this.xSpeed;
          this.container.scale.x = -1;
          this.foothold = this.footholdtree[this.foothold.next];
        } else {
          if (this.footholdtree[this.foothold.prev]) {
            this.foothold = this.footholdtree[this.foothold.prev];
          }
        }
      }
    } else if (this.isRight() && !this.isDie && !this.isAttacked) {
      this.position.x += this.xSpeed;
      if (this.position.x > this.foothold.x2) {
        if (this.foothold.isWall()) {
          this.position.x -= this.xSpeed;
          this.container.scale.x = 1;
          this.foothold = this.footholdtree[this.foothold.prev];
        } else {
          if (this.footholdtree[this.foothold.next]) {
            this.foothold = this.footholdtree[this.foothold.next];
          }
        }
      }
    } else {

    }
    this.numUpdate();
  }
  transform(goalAniName) {
    if (this.state === goalAniName) {
      return;
    }
    if (goalAniName === "hit1") {
      this.container.addChild(this.afterImageHit.sword1);
      this.afterImageHit.sword1.gotoAndPlay(0);
      this.afterImageHit.sword1.onComplete = () => {
        this.container.removeChild(this.afterImageHit.sword1);
      };
    }

    this.state = goalAniName;
    let nextAni = this.performance[goalAniName];
    let nowAni = this.animationSprite;
    this.container.removeChild(nowAni);
    this.animationSprite = nextAni;
    this.animationSprite.gotoAndPlay(0);
    this.container.addChild(this.animationSprite);
    this.container.zIndex = 10000;
  }
  isLeft() {
    return this.container.scale.x === 1;
  }

  isRight() {
    return this.container.scale.x === -1;
  }

  attack(player) {
    if (this.isDie) {
      return -1;
    }
    if (this.position.x - this.container.width / 2 <= player.position.x + player.getWidth() / 2) {
      if (this.position.x + this.container.width / 2 >= player.position.x - player.getWidth() / 2) {
        if (this.position.y - this.container.height <= player.position.y) {
          if (this.position.y >= player.position.y - player.container.height) {
            // 判断从那边攻击
            if (this.position.x < player.position.x) {
              return 0;
            } else {
              return 1;
            }
          }
        }
      }
    } 
    return false;
  }

  attacked(number) {
    if (this.isDie) {
      return ;
    }
    if (number !== 0) {
      this.isAttacked = true;
    }
    this.transform('hit1');
    this.hurt(number);
    this.ability.nowHP -= number;
    if (this.ability.nowHP <= 0) {
      this.die();
    }
  }

  die() {
    this.isDie = true;
  }
}

class Hurt {
  hurt(num) {
    this.descreaseBlood(num);
  }
  numUpdate() {
    this.numberArray.forEach((num) => {
      if (num.numNowHeight <= this.numHeight) {
        num.y =
          this.position.y - Math.abs(this.animationSprite.height) - num.numNowHeight - num.height; 
        num.x = this.position.x - num.width / 2;
        num.numNowHeight += this.numSpeed;
      } else {
        share.stage.removeChild(num);
        this.numberArray.shift();
      }
    });
  }
  addNum(num) {
    this.numberArray.push(num);
    num.y = this.position.y - Math.abs(this.animationSprite.height) - num.numNowHeight - num.height;
    num.x = this.position.x - num.width / 2;
    share.stage.addChild(num);
    num.numNowHeight = 0;
  }
  descreaseBlood(num) {
    let numSprite = share.numbers.getSprite(num, "NoRed");
    this.addNum(numSprite);
  }
}

applyMixins(Mob, [Hurt]);
